/**
 * Copyright 2011 Google
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.appengine.codelab;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PropertyProjection;
import com.google.appengine.api.datastore.Query;

/**
 * This class defines the methods for basic operations of create, update &
 * retrieve
 * 
 * @author
 * 
 */
public class Transacao {
	// private static final Logger logger = Logger.getLogger(Transacao.class.getCanonicalName());

	/**
	 * Create or update Transacao
	 * 
	 * @param trans_type
	 *            : type of the transacao
	 * @param trans_price
	 *            : price of the transacao
	 * @param trans_data
	 *            : date of the transacao
	 * @param trans_hora
	 *            : hours of the transacao
	 * @return
	 */
	public static Entity createOrUpdateTransacao(String trans_id,
			String trans_type, Double trans_price, String trans_data,
			String trans_hora, String estabelecimento_id, String cliente_id,
			String midia_id, String localidade_id) {
		Entity transacao = getSingleTransacao(trans_id);
		Entity cliente = Cliente.getSingleCliente(cliente_id);
		Entity estabelecimento = Estabelecimento
				.getSingleEstabelecimento(estabelecimento_id);
		Entity midia = Midia.getSingleMidia(midia_id);
		Entity localidade = Localidade.getSingleLocalidade(localidade_id);

		if (transacao == null) {
			transacao = new Entity("Transacao", trans_id);
			transacao.setProperty("trans_id", trans_id);
			transacao.setProperty("trans_type", trans_type);
			transacao.setProperty("trans_price", trans_price);
			transacao.setProperty("trans_data", trans_data);
			transacao.setProperty("trans_hora", trans_hora);
			transacao.setProperty("estabelecimento_id", estabelecimento
					.getProperty("estabelecimento_id").toString());
			transacao.setProperty("cliente_id",
					cliente.getProperty("cliente_id").toString());
			transacao.setProperty("midia_id", midia.getProperty("midia_id")
					.toString());
			transacao.setProperty("localidade_id",
					localidade.getProperty("localidade_id").toString());

		} else {
			if (trans_type != null && !"".equals(trans_type)) {
				transacao.setProperty("trans_type", trans_type);
			}
			if (trans_price != null) {
				transacao.setProperty("trans_price", trans_price);
			}
			if (trans_data != null) {
				transacao.setProperty("trans_data", trans_data);
			}
			if (trans_hora != null && !"".equals(trans_hora)) {
				transacao.setProperty("trans_hora", trans_hora);
			}
		}
		Util.persistEntity(transacao);
		return transacao;
	}

	public static List<String> listarTiposTransacao() {
		Query query = new Query("Transacao");
		query.addProjection(new PropertyProjection("trans_type", String.class));
		query.setDistinct(true);

		Iterable<Entity> iterable = DatastoreServiceFactory
				.getDatastoreService().prepare(query).asIterable();
		List<String> tipos = new ArrayList<String>();

		for (Entity entity : iterable) {
			tipos.add((String) entity.getProperty("trans_type"));
		}

		return tipos;
	}

	/**
	 * get All the transacaos in the list
	 * 
	 * @param kind
	 *            : transacao kind
	 * @return all the transacaos
	 */
	public static Iterable<Entity> getAllTransacoes() {
		Iterable<Entity> entities = Util.listEntities("Transacao", null, null);
		return entities;
	}

	/**
	 * Get the transacao given the name
	 * 
	 * @param transacaoName
	 *            : transacao name
	 * @return Transacao Entity
	 */
	public static Iterable<Entity> getTransacao(String trans_id) {
		Iterable<Entity> entities = Util.listEntities("Transacao", "trans_id",
				trans_id);
		return entities;
	}

	/**
	 * Get all the transacoes for a midia
	 * 
	 * @param kind
	 *            : transacao kind
	 * @param midiaName
	 *            : midia name
	 * @return: all transacaos of type midia
	 */
	public static Iterable<Entity> getTransacaoForMidia(String kind,
			String midiaName) {
		Key ancestorKey = KeyFactory.createKey("Midia", midiaName);
		return Util.listChildren("Transacao", ancestorKey);
	}

	/**
	 * Get all the transacao for a cliente
	 * 
	 * @param kind
	 *            : transacao kind
	 * @param clienteName
	 *            : cliente name
	 * @return: all transacao of type cliente
	 */
	public static Iterable<Entity> getTransacaoForCliente(String clienteName) {
		ArrayList<Entity> list = new ArrayList<Entity>();
		Iterable<Entity> entities = Util.listEntities("Transacao", null, null);
		for (Entity entity : entities) {
			String clienteId = entity.getProperty("cliente_id").toString();
			Entity cliente = Cliente.getSingleCliente(clienteId);
			if (clienteName.equals(cliente.getProperty("cliente_name")
					.toString())) {
				list.add(entity);
			}
		}
		return list;
	}

	/**
	 * Get all the transacao for a midia number
	 * 
	 * @param kind
	 *            : transacao kind
	 * @param midiaNumber
	 *            : midia number
	 * @return: all transacao of type midia
	 */
	public static Iterable<Entity> getTransacaoForMidiaNumber(String midiaNumber) {
		ArrayList<Entity> list = new ArrayList<Entity>();
		Iterable<Entity> entities = Util.listEntities("Transacao", null, null);
		for (Entity entity : entities) {
			String midiaId = entity.getProperty("midia_id").toString();
			Entity midia = Midia.getSingleMidia(midiaId);
			if (midiaNumber
					.equals(midia.getProperty("midia_number").toString())) {
				list.add(entity);
			}
		}
		return list;
	}

	/**
	 * Get all the transacao for a localidade_id
	 * 
	 * @param kind
	 *            : transacao kind
	 * @param localidadeId
	 *            : localidadeId
	 * @return: all transacao of type localidade
	 */
	public static Iterable<Entity> getTransacaoForLocalidade(String localidadeId) {
		ArrayList<Entity> list = new ArrayList<Entity>();
		Iterable<Entity> entities = Util.listEntities("Transacao", null, null);
		for (Entity entity : entities) {
			String localId = entity.getProperty("localidade_id").toString();
			Entity midia = Localidade.getSingleLocalidade(localId);
			if (localidadeId.equals(midia.getProperty("localidade_id")
					.toString())) {
				list.add(entity);
			}
		}
		return list;
	}

	/**
	 * get Transacao with transacao name
	 * 
	 * @param transacaoName
	 *            : get transacaoName
	 * @return transacao entity
	 */
	public static Entity getSingleTransacao(String trans_id) {
		Iterable<Entity> results = Util.listEntities("Transacao", "trans_id",
				trans_id);
		List<Entity> entity = new ArrayList<Entity>();
		for (Entity e : results)
			if (e != null)
				entity.add(e);
		if (!entity.isEmpty()) {
			return (Entity) entity.remove(0);
		}
		return null;
	}
	
	public static void updateSessao(String trans_id, long ses_id) {
		Entity transacao = getSingleTransacao(trans_id);
		Entity sessao = new Sessao().get(ses_id);
		if (transacao != null && sessao != null) {
			transacao.setProperty("ses_id", ses_id);
		}
		Util.persistEntity(transacao);
	}	
	// Metodo Adicionado por Anderson - US2 
	 public static Iterable<Entity> getTransacaoFraudulentas(String trans_data_init,String trans_data_end) {
		    Iterable<Entity> entities = Util.listEntitiesFraudulentas("Transacao", "trans_data", trans_data_init, trans_data_end);
		    
		    return entities;
	   }
	// Metodo Adicionado por Anderson - US13
	 public static Iterable<Entity> getTransacaoPeriodoTipo(String trans_data_init,String trans_data_end, String trans_type) {
		    Iterable<Entity> entities = Util.listEntitiesTransacaoPeriodoTipo(trans_data_init, trans_data_end, trans_type);
		    
		    return entities;
	   }

}
